package main.java.com.stylinlin.nio;

import com.sun.istack.internal.Nullable;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Arrays;

/**
 * NioTest
 * buffer缓冲区核心要点, 读取缓冲区的数据/写数据到缓冲区中
 *
 * @author jonlin
 * @date 2020/7/2
 */
public class NioTest {
    public static void main(String[] args) throws FileNotFoundException {
//        testBuff();

//        testChannel();

        testCopyFile();
    }

    /**
     * 测试复制文件
     */
    private static void testCopyFile() {
        String sourceFilePath = NioTest.class.getResource("/").getFile() + "main/resource/aa.txt";
        String targetPath = NioTest.class.getResource("/").getFile() + "main/resource/copy.txt";
        copyFile(sourceFilePath.substring(1, sourceFilePath.length()), targetPath.substring(1, targetPath.length()));
    }
    /**
     * 复制文件
     */
    private static void copyFile(String sourceFilePath, String targetPath) {
        File targetFile = new File(targetPath);
        if(!targetFile.exists()){
            try {
                targetFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        try (
                FileChannel fileIn = FileChannel.open(Paths.get(sourceFilePath), StandardOpenOption.READ);
                FileChannel fileOut = FileChannel.open(Paths.get(targetPath), StandardOpenOption.READ, StandardOpenOption.WRITE);
        ) {
            // 内存映射文件
            MappedByteBuffer inMappedByteBuffer = fileIn.map(FileChannel.MapMode.READ_ONLY, 0, fileIn.size());
            MappedByteBuffer outMappedByteBuffer = fileOut.map(FileChannel.MapMode.READ_WRITE, 0, fileIn.size());

            byte[] ds = new byte[(int) fileIn.size()];

            byte[] bytes = new byte[1024];
            for (int offSet = 0; offSet < fileIn.size(); offSet++){
                byte b = inMappedByteBuffer.get();
                ds[offSet] = b;
                System.out.println(String.valueOf(b));
            }
            System.out.println(Arrays.toString(ds));

//            while (inMappedByteBuffer.get(bytes).){
//                byteBuffer.flip();
//                fileOut.write(byteBuffer);
//                byteBuffer.clear();
//            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * nio读取文件
     */
    private static void testChannel() {
        String filePath = NioTest.class.getResource("/").getFile() + "main/resource/aa.txt";
        filePath = filePath.substring(1, filePath.length());
        ByteBuffer byteBuffer = ByteBuffer.allocate(16);
        try (FileChannel fileChannel = FileChannel.open(Paths.get(filePath), StandardOpenOption.READ);) {
            // 通道开启
            fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, fileChannel.size());
//            showBuff(byteBuffer);

            // 读入缓冲区
            while (fileChannel.read(byteBuffer) != -1) {
//                showBuff(byteBuffer);

                // 切换到读取模式
                byteBuffer.flip();

                // 输出显示
                byte[] bytes = new byte[byteBuffer.limit()];
                byteBuffer.get(bytes);
                System.out.print(new String(bytes));

                // 清除缓冲区
                byteBuffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     * 测试 ByteBuffer
     */
    private static void testBuff() {
        // 创建一个缓冲区
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

        // 看一下初始时4个核心变量的值
        showBuff(byteBuffer);

        // 添加一些数据到缓冲区中
        String s = "Java3y";
        byteBuffer.put(s.getBytes());

        // 看一下初始时4个核心变量的值
        showBuff(byteBuffer);

        byteBuffer.flip();

        // 看一下初始时4个核心变量的值
        showBuff(byteBuffer);

        System.out.println("--------------------------------------");

        byte[] bytes = new byte[byteBuffer.limit()];
        byteBuffer.get(bytes);
        System.out.println(new String(bytes));

        // 看一下初始时4个核心变量的值
        showBuff(byteBuffer);

        byteBuffer.clear();

        // 看一下初始时4个核心变量的值
        showBuff(byteBuffer);
    }

    /**
     * 看下核心变量值
     *
     * @param byteBuffer
     */
    private static void showBuff(ByteBuffer byteBuffer) {
        // 看一下初始时4个核心变量的值
        System.out.println("get 完之后-->limit--->" + byteBuffer.limit());
        System.out.println("get 完之后-->position--->" + byteBuffer.position());
        System.out.println("get 完之后-->capacity--->" + byteBuffer.capacity());
        System.out.println("get 完之后-->mark--->" + byteBuffer.mark());

        System.out.println("--------------------------------------");
    }
}
